/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bff.slimserver.musicjukebox.ui.components.podcast;

import com.bff.slimserver.music.exceptions.PlaylistException;
import com.bff.slimserver.musicjukebox.lib.JukeboxProperties;
import com.bff.slimserver.musicjukebox.ui.SplashScreen;
import com.bff.bjj.utils.Utils;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.bff.slimserver.SlimPlaylist;
import org.bff.slimserver.SlimPodcaster;
import org.bff.slimserver.exception.SlimConnectionException;
import org.bff.slimserver.musicobjects.SlimPodcastItem;

/**
 *
 * @author bfindeisen
 */
public class PodcastTree extends JTree implements TreeWillExpandListener {

    private SlimPodcaster podcaster;
    private SlimPlaylist playlist;
    private List<SlimPodcastItem> podcastList;
    private static DefaultMutableTreeNode top = new DefaultMutableTreeNode("Podcasts");
    private SplashScreen sp;
    private static List<SlimPodcastItem> loadedList;

    public PodcastTree() {
        super(top);

        getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //setShowsRootHandles(true);

        try {
            setPlaylist(JukeboxProperties.getInstance().getPlaylist());
        } catch (PlaylistException ex) {
            Logger.getLogger(PodcastList.class.getName()).log(Level.SEVERE, null, ex);
        }

        try {
            setPodcaster(JukeboxProperties.getInstance().getPodcaster());
        } catch (SlimConnectionException ex) {
            Logger.getLogger(PodcastList.class.getName()).log(Level.SEVERE, null, ex);
        }

        setCellRenderer(new PodcastTreeCellRenderer());
        //addTreeSelectionListener(this);
        //listAll();
        //addMouseListener(this);
        addTreeWillExpandListener(this);
    }

    public void listAll() throws Exception {

        loadedList = new ArrayList<SlimPodcastItem>();

        setModel(new DefaultTreeModel(top));

        podcastList = new ArrayList<SlimPodcastItem>(getPodcaster().getPodcastList());

        for (SlimPodcastItem podcast : podcastList) {
            DefaultMutableTreeNode category = new DefaultMutableTreeNode(podcast);
            if (podcast.isError()) {
                DefaultMutableTreeNode errorMsg = new DefaultMutableTreeNode(podcast.getErrorMessage());
                category.add(errorMsg);
            } else {


                //for (SlimPodcastItem item : podcast.getPodcastItems()) {


                //if (!item.isAudio()) {
                //DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(podcast);
                //category.add(itemNode);
                //top.add(category);
                if (itemHasItems(podcast)) {
                    category.add(new DefaultMutableTreeNode());
                }
                //}
                //}
            }

            top.add(category);
        }
        expandRow(0);
        //setRootVisible(false);

    }

    /**
     * @return the podcaster
     */
    public SlimPodcaster getPodcaster() {
        return podcaster;
    }

    /**
     * @param podcaster the podcaster to set
     */
    public void setPodcaster(SlimPodcaster podcaster) {
        this.podcaster = podcaster;
    }

    /**
     * @return the playlist
     */
    public SlimPlaylist getPlaylist() {
        return playlist;
    }

    /**
     * @param playlist the playlist to set
     */
    public void setPlaylist(SlimPlaylist playlist) {
        this.playlist = playlist;
    }

    /**
     * @return the podcastList
     */
    public List<SlimPodcastItem> getPodcastList() {
        return podcastList;
    }

    /**
     * @param podcastList the podcastList to set
     */
    public void setPodcastList(List<SlimPodcastItem> podcastList) {
        this.podcastList = podcastList;
    }

    /**
     * @return the selectedPodcast
     */
    public SlimPodcastItem getSelectedPodcast() {
        TreePath path = getSelectionPath();
        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
        if (node == null) //Nothing is selected.
        {
            return null;
        }

        Object nodeInfo = node.getUserObject();

        if (nodeInfo instanceof SlimPodcastItem) {
            return (SlimPodcastItem) nodeInfo;
        }

        return null;
    }

    private synchronized void loadItem(DefaultMutableTreeNode node, SlimPodcastItem podcastItem) {


        node.remove(0);
        ((DefaultTreeModel) getModel()).reload(node);

        getPodcaster().loadPodcastItem(podcastItem);

        List<SlimPodcastItem> podcastItems =
                new ArrayList<SlimPodcastItem>(podcastItem.getPodcastItems());


        for (SlimPodcastItem item : podcastItems) {

            if (item.isError()) {
                DefaultMutableTreeNode errorMsg = new DefaultMutableTreeNode(item.getErrorMessage());
                node.add(errorMsg);
            } else {
                DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(item);

                //if (!item.isAudio()) {
                if (itemHasItems(item)) {
                    node.add(itemNode);
                }
            }
        }
    }

    private boolean itemHasItems(SlimPodcastItem item) {
        return !item.isAudio() && item.isContainsItems();
    }

    public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
        
        TreePath path = event.getPath();
//        if (path != null) {
//            DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) path.getLastPathComponent();
//            DefaultMutableTreeNode kid = (DefaultMutableTreeNode) currentNode.getChildAt(0);
//            if (kid.getUserObject().equals(new DefaultMutableTreeNode("")))  {
//                setSelectionPath(new TreePath(currentNode.getPath()));
//                //populateNode();
//                makeVisible(new TreePath(((DefaultMutableTreeNode) currentNode.getChildAt(0)).getPath()));
//            }
//        }

        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
        if (node == null) //Nothing is selected.
        {
            return;
        }

        Object nodeInfo = node.getUserObject();

        if (nodeInfo instanceof SlimPodcastItem) {

            final SlimPodcastItem item = (SlimPodcastItem) nodeInfo;
            boolean loaded = loadedList.contains(item);
            if (!loaded) {
                //node.remove(0);
                sp = new SplashScreen(Utils.getParentComponent(this), true);
                sp.setIndeterminate(true);
                sp.setTitleLabel("Loading Podcast");
                sp.setMainTextArea("\nLoading pocast " + item.getName() + "\n\n");
                sp.setProgressBarLabel("Loading podcast...");
                sp.pack();

                new Thread(new Runnable() {
                    public void run() {
                        loadItem(node, item);
                        sp.setStopped(true);
                        ((DefaultTreeModel) getModel()).reload(node);
                        if (node.getChildCount() == 0) {
                            setSelectionPath(getPath(node));
                        } else {
                            expandPath(getPath(node));
                        }
                    }
                }).start();
            }
            loadedList.add(item);
        }


    }

    public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public TreePath getPath(TreeNode node) {
        List list = new ArrayList();

        // Add all nodes to list
        while (node != null) {
            list.add(node);
            node = node.getParent();
        }
        Collections.reverse(list);

        // Convert array of nodes to TreePath
        return new TreePath(list.toArray());
    }

    private class PodcastTreeCellRenderer extends DefaultTreeCellRenderer {

        private Icon iconRoot = new ImageIcon(getClass().getResource("/resources/slimserver/podcaster_icon_small.jpg"));

        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {

            if (((DefaultMutableTreeNode)value).isRoot()) {
                setIcon(iconRoot);
                setText(((DefaultMutableTreeNode)value).toString());
            } else {
                return super.getTreeCellRendererComponent(
                    tree,
                    value,
                    selected,
                    expanded,
                    leaf,
                    row,
                    hasFocus);
            }

            return this;

        }
    }
}
